package model.dao;

import java.util.Date;
import javax.persistence.EntityManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import model.util.EntityManagerUtil;
import model.domain.Sprint;
import java.util.List;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import model.domain.Project;


@Repository
@Transactional
public class SprintDao {
private static final Log log = LogFactory.getLog(SprintDao.class);


	@PersistenceContext
	private EntityManager entityManager;

	public void insert(Sprint transientInstance) {
		log.debug("inserting Sprint instance");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			entityManager.getTransaction().begin();
			entityManager.persist(transientInstance);
			entityManager.getTransaction().commit();
			log.debug("insert successful");
		} catch (RuntimeException re) {
			log.error("insert failed", re);
			throw re;
		}
	}

	public void delete(Sprint persistentInstance) {
		log.debug("deleting Sprint instance");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			entityManager.getTransaction().begin();
			persistentInstance = entityManager.merge(persistentInstance);
			entityManager.remove(persistentInstance);
			entityManager.getTransaction().commit();
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
	}

	public void insertOrUpdate(Sprint detachedInstance) {
		log.debug("inserting or updating Sprint instance");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			entityManager.getTransaction().begin();
			detachedInstance = entityManager.merge(detachedInstance);
			entityManager.persist(detachedInstance);
			entityManager.getTransaction().commit();
			log.debug("insert or update successful");
		} catch (RuntimeException re) {
			log.error("insert or update failed", re);
			throw re;
		}
	}

	public Sprint findById(Integer id) {
		log.debug("getting Sprint instance with id: " + id);
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			Sprint instance = entityManager.find(Sprint.class, id);
			log.debug("get successful");
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}
	
	public List<Sprint> getAll() {
		log.debug("getting all Sprint instances");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			@SuppressWarnings("unchecked")
			Query query = entityManager.createQuery("from Sprint");
			log.debug("get successful");
			return query.getResultList();
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

        public List<Sprint> findByProject(Project project) {
		log.debug("getting all Sprint instances by Project");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			@SuppressWarnings("unchecked")
			Query query = entityManager.createQuery("SELECT s FROM Sprint s WHERE s.project = :project");
                        query.setParameter("project", project);
			log.debug("get successful");
			return query.getResultList();
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

        public Sprint findByDate(Date date, Project project) {
		log.debug("getting all Sprint instances by Date and Project");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			@SuppressWarnings("unchecked")
			Query query = entityManager.createQuery("SELECT s FROM Sprint s WHERE s.project = :project"
                                + " and s.start <= :date and s.end >= :date");
                        query.setParameter("project", project);
                        query.setParameter("date", date);
			log.debug("get successful");
                        List<Sprint> list = query.getResultList();
                        if (list.size() > 0)
                            return list.get(0);
                        else
                            return null;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}

        public Long countSprints(Project project){
		log.debug("getting all Sprint instances by Project");
		try {
			entityManager = EntityManagerUtil.getEntityManager();
			@SuppressWarnings("unchecked")
			Query query = entityManager.createQuery("SELECT count(s) FROM Sprint s WHERE s.project = :project");
                        query.setParameter("project", project);
			log.debug("get successful");
                        List<Long> list = query.getResultList();
                        return list.get(0);
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
        }
}
